<?php

/*------------------------------------------------
*
*   Explay Engine Content Management System.
*   Copyright © 2008 Golovdinov Alexander.
*
*-------------------------------------------------
*
*   Official site: wwww.alex-home.spb.ru/explay.html
*   Contact e-mail: golovdinov@gmail.com
*
*   GNU General Public License original source:
*   http://www.gnu.org/licenses/gpl-3.0.html
*
------------------------------------------------*/


if (!defined ('EXPLAY')) exit;

//
// expl_hash($str) возвращает хеш строки $str

function expl_hash($str) {
	if (function_exists('sha1'))
		return sha1($str); 
	elseif (function_exists('mhash'))
		return bin2hex(mhash(MHASH_SHA1, $str));
	else
		return md5($str);
}



//
// _get ($par, $option = 'option') возвращает название каталога
// под порядковым номером $par из параметра $_GET['option']
// вида 1/2/3/4

function _get ($par, $option = 'option') {
	if (isset($_GET['option'])) {
		$string = htmlspecialchars (trim ($_GET[$option]));
		$string = explode ('/', $string);
		$arr = array ();
		
		for ($i=1; $i<=count($string); $i++) {
			if (mb_strlen ($string[$i-1]) > 0) $arr[$i] = $string[$i-1];
		}
		
		if (isset($arr[$par]))
			return $arr[$par];
		else
			return '';
	}
	else return '';
}




//
// Функции обработки строк

function clear_danger_html ($string) {
	$string = preg_replace ("#onclick=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onmouseover=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onmouseout=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onmousedown=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onmouseup=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onselect=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onfocus=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onblur=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onload=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onkeydown=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onkeyup=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#ondblclick=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onunload=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onmouseup=[\"|\'](.+?)[\"|\']#is", '', $string);
	$string = preg_replace ("#onsubmit=[\"|\'](.+?)[\"|\']#is", '', $string);
	
	
	return $string;
}

function n2br ($string) {
	$string = str_replace ("\n", '<br />', $string);
	$string = str_replace ("\r", '', $string);
	return $string;
}

function input_video ($string) {
	
	$string = preg_replace ("#\<youtube>http://ru.youtube.com/watch\?v=(.+?)</youtube>#is",
	"\r\n<object width=\"425\" height=\"355\">
	<param name=\"movie\" value=\"http://www.youtube.com/v/\\1\"></param>
	<param name=\"wmode\" value=\"transparent\"></param>
	<embed src=\"http://www.youtube.com/v/\\1\" type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"425\" height=\"355\"></embed>
</object>", $string);		

	$string = preg_replace ("#\<youtube>http://youtube.com/watch\?v=(.+?)</youtube>#is",
	"\r\n<object width=\"425\" height=\"355\">
	<param name=\"movie\" value=\"http://www.youtube.com/v/\\1\"></param>
	<param name=\"wmode\" value=\"transparent\"></param>
	<embed src=\"http://www.youtube.com/v/\\1\" type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"425\" height=\"355\"></embed>
</object>", $string);		
		
	$string = preg_replace ("#\<rutube>http://rutube.ru/tracks/(.+?).html\?(.+?)v=(.+?)</rutube>#is",
	"\r\n<OBJECT width=\"400\" height=\"353\">
	<PARAM name=\"movie\" value=\"http://video.rutube.ru/\\3\" />
	<PARAM name=\"wmode\" value=\"window\" />
	<PARAM name=\"allowFullScreen\" value=\"true\"></PARAM>
	<EMBED src=\"http://video.rutube.ru/\\3\" type=\"application/x-shockwave-flash\" wmode=\"window\" width=\"400\" height=\"353\" allowFullScreen=\"true\" />
</OBJECT>", $string);

	$string = preg_replace ("#\<vimeo>http://vimeo.com/(.+?)</vimeo>#is",
	"\r\n<object width=\"400\" height=\"300\">
	<param name=\"allowfullscreen\" value=\"true\" />
	<param name=\"allowscriptaccess\" value=\"always\" />
	<param name=\"movie\" value=\"http://www.vimeo.com/moogaloop.swf?clip_id=\\1&server=www.vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1\" />
	<embed src=\"http://www.vimeo.com/moogaloop.swf?clip_id=\\1&server=www.vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1\" type=\"application/x-shockwave-flash\" allowfullscreen=\"true\" allowscriptaccess=\"always\" width=\"400\" height=\"300\"></embed>
</object>", $string);
	
	return $string;
}

function replace_symbols ($string) { 
	
	$string = str_replace ('«', '&laquo;', $string);
	$string = str_replace ('»', '&raquo;', $string);
	$string = str_replace ('—', '&mdash;', $string);
	$string = str_replace ('©', '&copy;', $string);
	
	return $string;
}



//
// Общая для всех модулей функция вывода комментариев
// $category - латинское название модуля под которым хранится комментарий
// $idi - id элемента модуля
// $url - адрес подставляеммый в ссылках от комментария
// $sort - сортировка (пустое значение или "DESC")

//
// Функия удаления комментария с $id

function delete_comment ($id) {
	global $db;
	
	$db->query ("DELETE FROM ".DB_PEREFIX."_comments WHERE com_id = '$id'");
	site_message ('Комментарий удален!');
}



//
// Функция добавления комментария
// $name - имя (для незарегистрированных пользователей)
// $mail - e-mail (для незарегистрированных пользователей)
// $body - текст комментария
// $category - латинское название модуля к которому относится комментарий
// $id - id элемента модуля
// $code - введенное пользователем значение CAPTCHA

function add_comment ($name, $mail, $body, $category, $id, $code) {
	global $SITE, $db, $template;
	
	$allowed_tags = array ("a","blockquote","i","em","b","strong","u","ul","ol","li","sup","table","tr","td","s","strike","font","img","nobr","abbr","acronym","pre","code","br");
	$allowed_string = '';
	foreach ($allowed_tags as $tag) $allowed_string .= '<'.$tag.'>';
	
	if (my_karma() > '-10') {
		$uid = 0;
		if (is_registered ()) $uid = User::$properties['user_id'];
		$body = strip_tags ($body, $allowed_string);
		$body = replace_symbols ($body);
		$name = strip_tags ($name);
		$error = '';
		$mail = str_replace ('mailto:', '', $mail);
		$mail = trim($mail);
		
		if ($mail == '' && is_registered()) $mail = User::$properties['user_email'];
		
		$parent = 0;
		
		if (!empty($_POST['parent'])) {
			if (is_registered()) {
				$parent = intval($_POST['parent']);
				$SITE['bot_protect'] = '';
			} else {
				$error .= '<li>Вы не можете отвечать на комментарии!</li>'; 
				$parent = 0;
			}
			
			// Берем e-mail родительского комментария
			$get_parent = $db->query ("SELECT com_mail, com_text FROM ".DB_PEREFIX."_comments WHERE com_id = ".intval($_POST['parent']));
				
			if ($db->num_rows ($get_parent) == 1)
				list($parent_mail, $parent_text) = $db->fetch_row ($get_parent);
			else
				$error .= '<li>Неправильный id родительского комментария!</li>';
			
		}
			
			
		
		
		if ($body == '') $error .= '<li>Не заполнено поле текста!</li>';
		if (is_registered()) {
			$name = '';
			$mail = '';
		} else {
			if ($name == '') $error .= '<li>Не заполнено имя!</li>';
			if (!eregi("^[a-z0-9\._-]+@[a-z0-9\._-]+\.[a-z]{2,4}\$",$mail)) $error .= '<li>Неверно заполнен e-mail!</li>';
		}
		
		// CAPTCHA проверяется только для незарегистрированных пользователей
		if ($SITE['bot_protect'] == 'yes' && !is_registered()) {
			if ($code != $_SESSION['secret_code'] || $code == '') $error .= '<li>Неверный код!</li>';
		}
		if (mb_strlen($name) > 25) $error .= '<li>Имя слишком длинное!</li>';
		if (mb_strlen($mail) > 40) $error .= '<li>E-mail слишком длинный!</li>';
		if (mb_strlen($body) > 5000) $error .= '<li>Текст слишком длинный!</li>';
		
		// "Таймер" для предотвращения многократного добавления комментариев с одной страницы
		//$timer = $db->num_rows ($db->query ("SELECT * FROM ".DB_PEREFIX."_comments WHERE com_category = '$category' AND com_idi = '$id' AND com_parent = 0 AND user_ip = '".$_SERVER['REMOTE_ADDR']."' AND com_date > ".(time()-300) ));
		//if ($timer > 0) $error .= '<li>Вы не можете оставлять комментарии так часто!';
		
		
		if ($error == '') {	
			
			$db->query("INSERT INTO ".DB_PEREFIX."_comments VALUES (0, '$uid', '$category', '$id', '".strip_tags($name)."', '".strip_tags($mail)."', '$body', '".time()."', '".$_SERVER['REMOTE_ADDR']."', '$parent', 0, '')");
			
			site_message ('Комментарий добавлен!');
			
			// Ответ на комментарий
			if (isset($parent_mail) && $parent_mail != '') {
				
				$comment = array ();
				$comment['author_url'] = 'http://'.$_SERVER['HTTP_HOST'].'/users/'.User::$properties['user_login'];
				$comment['author_name'] = User::$properties['user_name'];
				$comment['parent_link'] = "http://".$_SERVER['HTTP_HOST']."/$category/{$id}.html#comment#comment".$parent;
				$comment['parent_body'] = $parent_text;
				$comment['body'] = $body;
				$comment['link'] = "http://".$_SERVER['HTTP_HOST']."/$category/{$id}.html#comment".mysql_insert_id();
				
				Templater::set_var ('comment', $comment);
				
				$body = Templater::display ('mail/comment_reply.tpl');
				
				if (!is_localhost ()) {
					mail (
						"$parent_mail <{$parent_mail}>",
						"Ответ на комментарий",
						$body,
						"From: ".$SITE['site_name']." <".$SITE['site_email'].">".
						"\nContent-Type: text/html; charset=\"utf-8\"".
						"\nContent-Transfer-Encoding: 8bit\n"
					);
				}
			}
			
		}
		else site_error ($error);
		
	}
	else site_error ('У Вас настолько низкая карма, что вы не можете добавлять комментарии.');
		
}



//
// Функция, проверяющяя существует ли (кеширован) файл $filename с датой модифицирования $time сек. назад

function is_cached ($filename, $time) {
	$file = $_SERVER['DOCUMENT_ROOT']."/include/cache/".$filename;
	if (file_exists ($file)) {
		if (filemtime ($file) > (time() - $time)) return true;
		else return false;
	}
	else return false;
}


//
// Создание файла в каталоге include/cache под именем $filename и контентом $content

function cache_file ($filename, $content) {
	$file = $_SERVER['DOCUMENT_ROOT']."/include/cache/".$filename;
	if (file_exists ($file)) unlink ($file);
	
	$cache_file = fopen ($file, 'w');
	flock ($cache_file, LOCK_EX);
	fwrite ($cache_file, $content);
	flock ($cache_file, LOCK_UN);
	fclose ($cache_file);
}

//
// Функция очищения кеша

function clear_cache () {
	$dir = opendir ($_SERVER['DOCUMENT_ROOT'].'/include/cache');
	chdir ($_SERVER['DOCUMENT_ROOT'].'/include/cache');
	
	while ($f = readdir ($dir)) {
		if (is_file ($f) && basename ($f) != '.htaccess') unlink ($f);
	}
	
	closedir ($dir);
	
	return true;
	
}



//
// Функция возвращает значение кармы текущего пользователя

function my_karma () {

	if (!is_registered())
		return (float) '0.0';
	elseif (is_admin())
		return (float) '99999.9';
	else
		return (float) User::$properties['user_karma'];
}



//
// Функция возвращает картинку со статусом пользователя $id

function user_status ($id) {
	global $theme, $db;

	$get_user = $db->query ("SELECT * FROM ".DB_PEREFIX."_sessions WHERE uid = '$id'");
	if ($db->num_rows ($get_user) == 1) {
		return "<img src=\"/themes/$theme/images/online.gif\" title=\"Пользователь on-line\" align=\"absmiddle\" /> ";
	}
	else return "<img src=\"/themes/$theme/images/offline.gif\" title=\"Пользователь off-line\" align=\"absmiddle\" /> ";
}




//
// Функия вывода постраничой навигации
//
// $start - начальное значение (не номер страницы)
// $number - количество эл-ов на странице
// $count - общее число элементов
// $url - основной URL ссылки
// $get_start_name - название GET параметра с которым передается номер страницы
// $after_url - дополнительные GET параметры
// $admin_panel - при естановке true навигация выведется в форме совместимой с панелью администратора

function past_pages ($start, $number, $count, $url, $get_start_name = 'page', $after_url = '', $admin_panel = false) {
	$g_start = $start;
	$pages = '';
	$p_count = ($start / $number) + 1;
	
	if ($count > $number) {
	
		if ($g_start > 0) {
			($admin_panel == true)
				? $pages .= "<a href=\"{$url}page=".(( ($g_start - $number) / $number ) + 1)."\">&#8592; вперед</a> "
				: $pages .= "<a href=\"$url{$get_start_name}".(( ($g_start - $number) / $number ) + 1)."/$after_url\">&#8592; вперед</a> ";
		}
		
		if ($start - $number >= 0) {
			$start_back = $start;
			
			$p_count_back = 1;
			$back_s = 0 - $number;
			$break = $start_back / $number;
			$i = 1;
			
			if ($start_back / $number >= 5)
			{
				($admin_panel == true)
					? $pages .= "<a href=\"{$url}page=1\">1</a> "
					: $pages .= "<a href=\"$url{$get_start_name}1/$after_url\">1</a> ... ";
				
				$back_s = $number - ($number - 4);
				$p_count_back = $start_back / $number - 3;
				$break = 5;
			}
			
			while ($start_back - $number >= 0) {
				if ($break == 5) if ($i >= $break) break;
				else if ($i > $break) break;
				
				if ($back_s + $number >= $start) break;
				
				if ($break != 5)
					($admin_panel == true)
						? $pages .= "<a href=\"{$url}page=".(( ($back_s + $number) / $number ) + 1)."\">".$p_count_back."</a> "
						: $pages .= "<a href=\"$url{$get_start_name}".(( ($back_s + $number) / $number ) + 1)."/$after_url\">".$p_count_back."</a> ";
				else
					($admin_panel == true)
						? $pages .= "<a href=\"{$url}page=".$p_count_back."\">".$p_count_back."</a> "
						: $pages .= "<a href=\"$url{$get_start_name}".$p_count_back."/$after_url\">".$p_count_back."</a> ";
				
				$p_count_back++;
				$back_s = $back_s + $number;
				$i++;
			}
		}
		$pages .= '<strong>'.$p_count.'</strong> ';
		if ($start + $number < $count) {
			
			$break = ($count - $start) / $number;
			$i = 1;			
			
			if (($count - $start) / $number > 4) $break = 5;
			
			while ($start + $number < $count) {
				
				if ($start + $number > $count) break;
				$p_count++;
				if ($i < $break) ($admin_panel == true)
										? $pages .= "<a href=\"{$url}page=".(( ($start + $number) / $number ) + 1)."\">".$p_count."</a> "
										: $pages .= "<a href=\"$url{$get_start_name}".(( ($start + $number) / $number ) + 1)."/$after_url\">".$p_count."</a> ";
				$last_page = (($start + $number) / $number ) + 1;
				$start = $start + $number;
				$i++;
			}
			
			if ($break == 5) ($admin_panel == true)
								? $pages .= " ... <a href=\"{$url}page={$last_page}\">{$last_page}</a> "
								: $pages .= " ... <a href=\"$url{$get_start_name}{$last_page}/$after_url\">{$last_page}</a> ";
		}
		
		if ($count > $g_start + $number) {
			($admin_panel == true)
				? $pages .= " <a href=\"{$url}page=".(( ($g_start + $number) / $number ) + 1)."\">назад &#8594;</a>"
				: $pages .= " <a href=\"$url{$get_start_name}".(( ($g_start + $number) / $number ) + 1)."/$after_url\">назад &#8594;</a>";
		}
		
		($admin_panel == true) 
			? $return = "\n<center>Всего: {$count}, Страницы: ".$pages."</center>\n"
			: $return = "\n<div class=\"pages\">Страницы: ".$pages."</div>\n";
		
		return $return;
	}
}


//
// Пользователь?

function is_registered () {
	if (User::$properties['user_id'] > 0)
		return true;
	else
		return false;
}

//
// Админ?

function is_admin () {
	if (User::$properties['user_group'] == "admin")
		return true;
	else
		return false;
}

//
// Модератор?

function is_moderator () {
	if (User::$properties['moderator'] == 1)
		return true;
	else
		return false;
}



//
// Функция преобразования времени

function format_time ($string) {
	global $SITE;
	
	$today = intval (date('H')) * 3600 + intval(date('i')) * 60 + intval(date('s'));
	
	// Если это было давно
	if (date ('Y', $string) != date ('Y')) $date = date ('d.m.Y H:i', $string);
	
	// Не более часа назад
	elseif ((time() - $string) < 3600) {
		$date = count_smth ((date ('i', (time() - $string))), array ('минуту', 'минуты', 'минут'),false).' назад';
	}
	
	// Сегодня
	elseif ((time() - $string) < $today) {
		$date = 'сегодня в '.date('H:i', $string);
	}
	
	// В течение года
	else {
		$date = date ($SITE['date_format'], $string);
		$date = str_replace ("January", "Января", $date);
		$date = str_replace ("February", "Февраля", $date);
		$date = str_replace ("March", "Марта", $date);
		$date = str_replace ("April", "Апреля", $date);
		$date = str_replace ("May", "Мая", $date);
		$date = str_replace ("June", "Июня", $date);
		$date = str_replace ("July", "Июля", $date);
		$date = str_replace ("August", "Августа", $date);
		$date = str_replace ("September", "Сентября", $date);
		$date = str_replace ("October", "Октября", $date);
		$date = str_replace ("November", "Ноября", $date);
		$date = str_replace ("December", "Декабря", $date);
	}
	return $date;
}

//
// Функция выводящяя нужную форму слова в зависимости от значения числа $cnt (определение падежа)
// переменная $case должна быть массивом состоящим из 3-х форм слова

function count_smth ($cnt, $case, $word = true) {
	$cnt1 = $cnt;
	$cnt = str_replace ('-', '', $cnt);
	
	(mb_strlen($cnt) == 1) ? $minus = 1 : $minus = 2;
	$temp1 = substr($cnt, mb_strlen($cnt)-$minus, mb_strlen($cnt));
	$temp2 = substr($cnt, mb_strlen($cnt)-2, mb_strlen($cnt));
	if ($cnt == 0) $count = (($word) ? 'нет ' : '0 ').$case[2];
	elseif ($temp2 == 11 || $temp2 == 12 || $temp2 == 13 || $temp2 == 14) $count = "$cnt1 ".$case[2];
	elseif ($cnt == 1) $count = "$cnt1 ".$case[0];
	elseif ($temp1 == 2 || $temp1 == 3 || $temp1 == 4) $count = "$cnt1 ".$case[1];
	else $count = "$cnt1 ".$case[2];
	
	return $count;

}


//
// Функция подобная предыдущей, только не выводящяя само число $cnt

function count_smth2 ($cnt, $case, $word = true) {
	$cnt = str_replace ('-', '', $cnt);
	
	(mb_strlen($cnt) == 1) ? $minus = 1 : $minus = 2;
	$temp1 = substr($cnt, mb_strlen($cnt)-$minus, mb_strlen($cnt));
	$temp2 = substr($cnt, mb_strlen($cnt)-2, mb_strlen($cnt));
	if ($cnt == 0) $count = (($word) ? 'нет ' : '0 ').$case[2];
	elseif ($temp2 == 11 || $temp2 == 12 || $temp2 == 13 || $temp2 == 14) $count = $case[2];
	elseif ($cnt == 1) $count = $case[0];
	elseif ($temp1 == 2 || $temp1 == 3 || $temp1 == 4) $count = $case[1];
	else $count = $case[2];
	
	return $count;

}


//
// Отправка E-mail

function send_mail ($to, $from, $from_mail, $title, $text) {
	if (!is_localhost ()) {
		if (mail ($to, $title, $text, "From: $from <$from_mail>\nContent-Type: text/html; charset=\"utf-8\"\nContent-Transfer-Encoding: 8bit\n"))
			return true;
		else
			return false;
	}
}

//
// localhost?
function is_localhost () {
	if ($_SERVER['HTTP_HOST'] == 'localhost' || $_SERVER['HTTP_HOST'] == '127.0.0.1' || $_SERVER['REMOTE_ADDR'] == '127.0.0.1') return true;

	return false;
	
}

//
// Обработчики ошибок

function myErrorHandler($errno, $errmsg, $filename, $linenum, $vars) {
	global $SITE;
	
    $errortype = array (
                1    => 'Error',
                2    => 'Warning',
                4    => 'Parsing Error',
                8    => 'Notice',
                16   => 'Core Error',
                32   => 'Core Warning',
                64   => 'Compile Error',
                128  => 'Compile Warning',
                256  => 'User Error',
                512  => 'User Warning',
                1024 => 'User Notice',
                2047 => 'All',
                2048 => 'Runtime Notice'
                );
	$user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE);


	$dt = date("Y-m-d H:i:s");
	$myip=getenv('REMOTE_ADDR');
	$err = "<error>\r\n";
	$err .= '<date>' . $dt . "</date>\r\n";
	$err .= '<ip>' . $myip . "</ip>\r\n";
	$err .= '<errno>' . $errno . "</errno>\r\n";
	$err .= '<type>' . $errortype[$errno] . "</type>\r\n";
	$err .= '<msg>' . $errmsg . "</msg>\r\n";
	$err .= '<script>' . $filename . "</script>\r\n";
	$err .= '<line>' . $linenum . "</line>\r\n";
	$err .= "</error>\r\n";
	
	clear_cache ();
	
	if ($errno != 8 && $errno != 2048) {
		log_error($err);
		error_500 ();
	}

}



function log_error($message) {
	global $SITE;

    $f=fopen($_SERVER['DOCUMENT_ROOT'].'/explaylogs/errorlog.txt','a+');
    fwrite($f,$message);
    fclose($f);
	
	send_mail($SITE['developer_email'], $SITE['site_name'], $SITE['site_email'], 'Error Log: ' . $_SERVER['HTTP_HOST'], $message);
}

function error_404 () {
	ob_end_clean ();
	header ("HTTP/1.0 404 Not Found");
	include $_SERVER['DOCUMENT_ROOT'].'/404.html';
	exit;
}
function error_403 () {
	ob_end_clean ();
	header ("HTTP/1.0 403 Forbidden");
	include $_SERVER['DOCUMENT_ROOT'].'/403.html';
	exit;
}
function error_500 () {
	ob_end_clean ();
	header ("HTTP/1.0 500 Internal Server Error");
	include $_SERVER['DOCUMENT_ROOT'].'/500.html';
	exit;
}

function redirect ($url) {
	ob_end_clean ();
	header ("Location: $url");
	exit;
}



//
// Функция, заменяющяя стандартную strtolower ()

function str_to_lower ($str) {
    return mb_strtolower ($str);
}


